数学模型

Wang Haihua

🍈 🍉🍊 🍋 🍌


移动平均法

移动平均法是常用的时间序列预测方法, 由于其简单而具有很好的实用价值。

一次移动平均法

设观测序列为 $y_{1}, \cdots, y_{T}$, 取移动平均的项数 $N<T$ 。一次移动平均值计算公式为 $$M_{t}^{(1)}(N)=\frac{1}{N}\left(y_{t}+y_{t-1}+\cdots+y_{t-N+1}\right)=\frac{1}{N} \sum_{i=0}^{N-1} y_{t-i}$$ 则有 $$M_{t}^{(1)}(N)=\frac{1}{N}\left(y_{t-1}+\cdots+y_{t-N}\right)+\frac{1}{N}\left(y_{t}-y_{t-N}\right)=M_{t-1}^{(1)}(N)+\frac{1}{N}\left(y_{t}-y_{t-N}\right)$$

$t+1$ 期的预测值为 $\hat{y}_{t+1}=M_{t}^{(1)}(N)$, 其预测标准误差为 $$ S=\sqrt{\frac{\sum_{t=N+1}^{T}\left(\hat{y}_{t}-y_{t}\right)^{2}}{T-N}} . $$ 如果将 $\hat{y}_{t+1}$ 作为 $t+1$ 期的实际值, 那么就可以用 $\hat{y}_{t+1}=M_{t}^{(1)}(N)$ 计算第 $t+2$ 期预测值 $\hat{y}_{t+2}$ 。一般地, 也可相应地求得以后各期的预测值。但由于越 远时期的预测, 误差越大,因此一次移动平均法一般仅应用于一个时期后的 预测值(即预测第 $t+1$ 期)。

案例

问题

汽车配件销售某年 1 12 月份的化油器销售量 (单位:只) 统 计数据见表18.1 中第 2 行, 试用一次移动平均法预测下一年 1 月的销售量。

月份 1 2 3 4 5 6 7 8 9 10 11 12 预测
y_(i) 423 358 434 445 527 429 426 502 480 384 427 446
N=3 405 412 469 467 461 452 469 455 430 419
N=5 437 439 452 466 473 444 444 448

建模

分别取 $N=3, N=5$, 按预测公式 $$ \begin{aligned} &\hat{y}_{t+1}(3)=M_{t}^{1}(3)=\frac{y_{t}+y_{t-1}+y_{t-2}}{3}, \quad t=3,4, \cdots, 12, \\ &\hat{y}_{t+1}(5)=M_{t}^{1}(5)=\frac{y_{t}+y_{t-1}+y_{t-2}+y_{t-3}+y_{t-4}}{5}, \quad t=5,6, \cdots, 12, \end{aligned} $$

计算

计算 3 个月和 5 个月移动平均预测值, 分别见表 $18.1$ 第 3 行和第 4 行。 $N=3$ 时, 预测的标准误差为 $56.5752, N=5$ 时, 预测的标准误差为 $39.8159$ 。

通过表可以看到, 实际数据波动较大, 经移动平均后, 随机波动明显减少, 且 $N$ 越大, 波动也越小。同时, 也可以看到, 一次移动平均法的预测标准误差还是有些大, 对于实际数据波动较大的序列, 一般较少采用此法进行预测。

代码

import numpy as np
y=np.array([423,358,434,445,527,429,426,502,480,384,427,446])
def MoveAverage(y,N):
    Mt=['*']*N
    for i in range(N+1,len(y)+2):
        M=y[i-(N+1):i-1].mean()
        Mt.append(round(M))
    return Mt
yt3=MoveAverage(y,3) 
s3=np.sqrt(((y[3:]-yt3[3:-1])**2).mean())
yt5=MoveAverage(y,5)
s5=np.sqrt(((y[5:]-yt5[5:-1])**2).mean())
print('N=3时,预测值:',yt3,',预测的标准误差:',s3)
print('N=5时,预测值:',yt5,',预测的标准误差:',s5)

简单移动平均使用的是等量加权策略,可以利用卷积,相应代码如下:

def sma(arr,n):
    weights=np.ones(n)/n
    return np.convolve(weights,arr)[n-1:-n+1]

另一种写法

import numpy as np
y=np.array([423,358,434,445,527,429,426,502,480,384,427,446])
n1=3; yt1=np.convolve(np.ones(n1)/n1,y)[n1-1:-n1+1]
s1=np.sqrt(((y[n1:]-yt1[:-1])**2).mean())
n2=5; yt2=np.convolve(np.ones(n2)/n2,y)[n2-1:-n2+1]
s2=np.sqrt(((y[n2:]-yt2[:-1])**2).mean())
print('N=3时,预测值:',yt1,',预测的标准误差:',s1)
print('N=5时,预测值:',yt2,',预测的标准误差:',s2)

二次移动平均法

当预测目标的基本趋势是在某一水平上下波动时, 可用一次移动平均 方法建立预测模型。当预测目标的基本䞟势与某一线性模型相吻合时, 常用二次移动平均法。但序列同时存在线性趋势与周期波动时, 可用趋势移动平 均法建立预测模型 $$ \hat{\boldsymbol{y}}_{T+m}=a_{T}+b_{T} m, \quad m=1,2, \cdots, $$ 其中 $a_{T}=2 M_{T}^{(1)}-M_{T}^{(2)}, b_{T}=\frac{2}{N-1}\left(M_{T}^{(1)}-M_{T}^{(2)}\right)$ 。